package com.icesoft.base.manager.suppose.validation.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.dfa.WordTree;
import com.icesoft.base.manager.suppose.validation.SensitiveWordForbidden;
import com.icesoft.core.web.helper.PathUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

@Slf4j
public class SensitiveWordForbiddenValidator implements ConstraintValidator<SensitiveWordForbidden, String> {
    private static final Map<String, WordTree> WORD_MAP = new HashMap<>();

    static {
        String systemConfig = "config/SensitiveWord.txt";
        Set<String> wordSet = new HashSet<>();
        try (InputStream inputStream = PathUtil.getPathInputStream(systemConfig);
             InputStreamReader read = new InputStreamReader(inputStream);
             BufferedReader br = new BufferedReader(read)) {
            String txt;
            while ((txt = br.readLine()) != null) {
                if (StrUtil.isNotBlank(txt)) {
                    wordSet.add(txt.toLowerCase());
                }
            }
        } catch (IOException e) {
            log.warn("impossibility exception", e);
        }
        for (String wordStr : wordSet) {
            String[] words = wordStr.split(",");
            if (words.length != 2) {
                log.warn("跳过不符合的词：{}", wordStr);
                continue;
            }
            WordTree wordTree = WORD_MAP.get(words[0]);
            if (wordTree == null) {
                wordTree = new WordTree();
                wordTree.setCharFilter(ch -> !Character.isWhitespace(ch));
                WORD_MAP.put(words[0], wordTree);
            }
            wordTree.addWord(words[1]);
        }
    }

    private String[] wordGroups;

    private boolean isContainGroup = false;

    @Override
    public void initialize(SensitiveWordForbidden constraintAnnotation) {
        wordGroups = constraintAnnotation.wordGroups();
        if (wordGroups.length == 0) {
            return;
        }
        for (String wordGroup : wordGroups) {
            if (WORD_MAP.containsKey(wordGroup)) {
                isContainGroup = true;
                return;
            } else {
                log.trace("组：{}，没有配置敏感词", wordGroup);
            }
        }
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (!isContainGroup || StringUtils.isEmpty(value)) {
            return true;
        }
        String valueLowerCase = value.toLowerCase();
        for (String wordGroup : wordGroups) {
            WordTree wordTree = WORD_MAP.get(wordGroup);
            if (wordTree == null) {
                continue;
            }
            String word = wordTree.match(valueLowerCase);
            if (word != null) {
                // 禁用默认提示信息
                context.disableDefaultConstraintViolation();
                // 设置提示语
                context.buildConstraintViolationWithTemplate("包含非法关键字“" + word + "”，").addConstraintViolation();
                return false;
            }
        }
        return true;
    }
}
